import { isDate, isNumber, isFunction, isObject, isArray } from './is.js'
/***
 * @description 格式化日期
 * @param val
 * @param formatStr 符号
 * @param flag 是否返回YYYY-MM-DD HH:mm:ss true 返回，false返回没有时间的日期
 * @returns {string | null}
 */
export const formatDate = function (val, formatStr, flag) {
  const date = new Date(val)
  if (!isDate(date)) throw new Error('参数不能转化为时间')
  const year = date.getFullYear()
  let month = date.getMonth() + 1
  let day = date.getDate()
  month = month < 10 ? `0${month}` : month
  day = day < 10 ? `0${day}` : day
  if (flag) {
    let hours = date.getHours()
    let minutes = date.getMinutes()
    let seconds = date.getSeconds()
    hours = hours < 10 ? `0${hours}` : hours
    minutes = minutes < 10 ? `0${minutes}` : minutes
    seconds = seconds < 10 ? `0${seconds}` : seconds
    return `${year}${formatStr}${month}${formatStr}${day}${formatStr} ${hours}:${minutes}:${seconds}`
  } else {
    return `${year}${formatStr}${month}${formatStr}${day}`
  }
}

/***
 * @description 格式化距离当前前后的时间
 * @param num
 * @param formatStr 符号
 * @param flag 是否返回YYYY-MM-DD HH:mm:ss
 * @returns {{distanceDate: (string|null), currentDate: (string|null)}}
 */
export const distanceFormatDate = function (num, formatStr, flag) {
  if (!isNumber(num)) throw new Error('距离的日期只能为数字')
  const date = new Date()
  const targetMilliseconds = date.getTime() + 1000 * 60 * 60 * 24 * num
  const distanceDate = formatDate(targetMilliseconds, formatStr, flag)
  return {
    currentDate: formatDate(date, formatStr, flag),
    distanceDate
  }
}

/**
 * @description 复制文本
 * @param text
 */
export const copyText = function (text) {
  return new Promise((resolve) => {
    // 创建input框获取需要复制的文本内容
    const copyInput = document.createElement('input')
    copyInput.value = text
    document.body.appendChild(copyInput)
    copyInput.select()
    document.execCommand('copy')
    copyInput.remove()
    resolve(true)
  })
}

/**
* @description 导出数据下载
* @param {blob} response 文件二进制流
* @param {string} fileName 文件名称
* @param {string} typeName 文件名称
*/
export const downLoad = function (response, fileName, typeName) {
  const time = new Date()
  const content = response
  const reader = new FileReader()
  reader.readAsText(response, 'utf8')
  reader.onload = () => {
    // 若无导出数据时后端可能返回不是Blob数据
    const blob = new Blob([content])
    if ('download' in document.createElement('a')) {
      // 非IE下载
      const eLink = document.createElement('a')
      eLink.download = fileName + formatDate(time, '') + '.' + typeName
      eLink.style.display = 'none'
      eLink.href = URL.createObjectURL(blob)
      document.body.appendChild(eLink)
      eLink.click()
      URL.revokeObjectURL(eLink.href) // 释放URL对象
      document.body.removeChild(eLink)
    } else {
      // IE10+下载
      navigator.msSaveBlob(blob, fileName)
    }
  }
}

/**
 * @description 深度克隆
 * @param obj 克隆对象
 * @returns _obj 经过克隆之后的对象
 */
export const cloneDeep = function (obj) {
  // 常见的非值直接返回
  if ([null, undefined, NaN, false].includes(obj)) return obj
  // 原始类型直接返回
  if (!isFunction(obj) && !isObject(obj)) return obj
  const o = isArray(obj) ? [] : {}
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      o[key] = isObject(obj[key]) ? cloneDeep(obj[key]) : obj[key]
    }
  }
  return o
}

/**
 * @description 对象转string
 * @param obj 克隆对象
 * @returns string 经过转换之后的string
 */
export const toJSON = function (obj) {
  return JSON.stringify(obj, (key, value) => {
    switch (true) {
      case typeof value === 'undefined':
        return 'undefined'
      case typeof value === 'symbol':
        return value.toString()
      case typeof value === 'function':
        return value.toString()
      default:
        break
    }
    return value
  })
}

/**
 * @description 将对象当作参数拼接到url上
 * @param baseUrl 需要拼接的url
 * @param obj 参数对象
 * @returns {string} 拼接后的对象
 * 例子:
 *  let obj = {a: '1', b: '2'}
 *  setObjToUrlParams('www.baidu.com', obj)
 *  ==>www.baidu.com?a=3&b=4
 */
export const setObjToUrlParams = function (baseUrl, obj) {
  let parameters = ''
  let url
  for (const key in obj) {
    parameters += key + '=' + encodeURIComponent(obj[key]) + '&'
  }
  parameters = parameters.replace(/&$/, '')
  if (/\?$/.test(baseUrl)) {
    url = baseUrl + parameters
  } else {
    url = baseUrl.replace(/\/?$/, '?') + parameters
  }
  return url
}

/**
 * @description 浏览器全屏\非全屏切换
 * @param fullElement
 */
export const screenFull = function (fullElement = document.documentElement) {
  // 判断是否处在全屏状态
  const isFullScreen = document.isFullScreen || document.mozIsFullScreen || document.webkitIsFullScreen
  if (isFullScreen) {
    const el = document
    const cfs = el.cancelFullScreen || el.mozCancelFullScreen || el.msExitFullscreen || el.webkitExitFullscreen || el.exitFullscreen
    cfs && cfs.call(el)
  } else {
    const el = fullElement
    const rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen
    rfs && rfs.call(el)
  }
}
